﻿#include "FITKAbaqusHDF5AdaptorPart.h"
#include "FITKAbaqusHDF5Reader.h"
#include "FITKAbaqusHDF5Writer.h"
#include "FITKAbaqusHDF5AdaptorSectionAssign.h"
#include "FITKAbaqusHDF5AdaptorCoordinateSystem.h"
#include "FITKAbaqusHDF5AdaptorMaterialOrientation.h"
#include "FITKAbaqusHDF5AdaptorInertia.h"

#include "FITK_Component/FITKAbaqusData/FITKDataCase.h"
#include "FITK_Component/FITKAbaqusData/FITKAbaqusPart.h"
#include "FITK_Interface/FITKInterfaceModel/FITKElementFactory.h"

#include "FITK_Kernel/FITKCore/FITKVec3D.h"
#include "FITK_Kernel/FITKCore/FITKEnumTransformer.hpp"
#include "FITK_Interface/FITKInterfaceModel/FITKUnstructuredMesh.h"
#include "FITK_Interface/FITKInterfaceModel/FITKModelSet.h"
#include "FITK_Interface/FITKInterfaceModel/FITKComponentManager.h"
#include "FITK_Interface/FITKInterfaceModel/FITKAbstractElement.h"
#include "FITK_Interface/FITKInterfaceModel/FITKElementHex.h"
#include "FITK_Interface/FITKInterfaceModel/FITKElementQuad.h"
#include "FITK_Interface/FITKInterfaceModel/FITKElementTet.h"
#include "FITK_Interface/FITKInterfaceModel/FITKElementTri.h"
#include "FITK_Interface/FITKInterfaceModel/FITKMeshSurface.h"
#include "FITK_Interface/FITKInterfaceModel/FITKMeshSurfaceNode.h"
#include "FITK_Interface/FITKInterfaceModel/FITKMeshSurfaceElement.h"

#include "FITK_Interface/FITKInterfacePhysics/FITKAbstractSection.h"
#include "FITK_Interface/FITKInterfacePhysics/FITKSectionAssign.h"
#include "FITK_Interface/FITKInterfacePhysics/FITKAbstractMaterial.h"

#include "FITK_Interface/FITKInterfaceStructural/FITKAbaMeshPartVTK.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaSectionBeam.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaSectionShellHomogeneous.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaSectionSolidHomogeneous.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaAbstractSection.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaProfile.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaProfileI.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaProfileManager.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaSectionAssignShellHomogeneous.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaSectionAssignSolidHomogenous.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaMaterialOrientation.h"

#include "FITK_Interface/FITKInterfaceIOHDF5/FITKInterfaceHDF5AdaptorSet.h"
#include "FITK_Interface/FITKInterfaceIOHDF5/FITKInterfaceHDF5AdaptorSurface.h"
#include "FITK_Interface/FITKInterfaceIOHDF5/FITKInterfaceHDF5AdaptorSectionAssign.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaSectionAssignBeam.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaAbstractInertia.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaEngineeringFeature.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaInertiaManager.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaBeamOrientation.h"

#include "FITK_Interface/FITKInterfaceModel/FITKCoordinateSystem.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaTransform.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaInertiaPointMassInertia.h"

#include "H5Cpp.h"

#include <array>
#include <QSet>
#include <QList>
#include <QMultiHash>
#include <QDebug>
namespace IO
{
    QString FITKAbaqusHDF5AdaptorPart::getAdaptorClass()
    {

        return "FITKAbaqusHDF5AdaptorPart";
    }

    bool FITKAbaqusHDF5AdaptorPart::adaptR()
    {
        _partData = AbaqusData::FITKAbaqusPart::SafeDownCastFITKAbaqusPart(_dataObj);
        if (!_partData || !_h5Group || !_reader) return false;
        bool isR = true;
        bool isValid = false;

        isR &= readNDataObject(_partData, *_h5Group);
        if (!_h5Group->nameExists("Grid")) return false;
        auto GridGroup = _h5Group->openGroup("Grid");

        //读取节点
        isR &= readNode(_partData, GridGroup);
        //读取单元
        isR &= readElement(_partData, GridGroup);
        //读取集合与表面
        isR &= readSetSurf(_partData, *_h5Group);

        if (!_h5Group->nameExists("SectionAssigns")) return false;
        auto sectionAssignsGroup = _h5Group->openGroup("SectionAssigns");
        //读取截面指派
        int sectionAssignCount = sectionAssignsGroup.getNumAttrs();
        for (int i = 0; i < sectionAssignCount; ++i)
        {
            auto name = readStrAttribute(sectionAssignsGroup, std::to_string(i));
            if (!sectionAssignsGroup.nameExists(name)) return false;
            auto sectionAssignGroup = sectionAssignsGroup.openGroup(name);
            if (!sectionAssignGroup.attrExists("Type")) return false;
            auto str = readStrAttribute(sectionAssignGroup, "Type");

            //枚举转换字符
            Core::FITKEnumTransfer<Interface::FITKAbaAbastractSectionAssign::FITKAbaSectionAssignType> fitkTypeTrafer;
            auto eType = fitkTypeTrafer.fromString(QString::fromStdString(str), isValid);
            if (!isValid) return false;

            isR &= readSectionAssign(eType, sectionAssignGroup);
        }

        //读取CoordinateSystemGroup子节点
                //读取Inertia子节点
        if (_h5Group->nameExists("CoordinateSystems"))
        {
            H5::Group CoordinateSystemsGroup = _h5Group->openGroup("CoordinateSystems");
            int coordinateSystemCount = CoordinateSystemsGroup.getNumAttrs();
            for (int i = 0; i < coordinateSystemCount; ++i)
            {
                auto name = readStrAttribute(CoordinateSystemsGroup, std::to_string(i));
                H5::Group CoordinateSystemGroup = CoordinateSystemsGroup.openGroup(name);
                isR &= readCoordinateSystem(CoordinateSystemGroup);
            }
        }
        //读取MaterialOrientationGroup子节点
        if (_h5Group->nameExists("MaterialOrientations"))
        {
            H5::Group materialOrientationsGroup = _h5Group->openGroup("MaterialOrientations");
            int materialOrientationsCount = materialOrientationsGroup.getNumAttrs();
            for (int i = 0; i < materialOrientationsCount; ++i)
            {
                auto name = readStrAttribute(materialOrientationsGroup, std::to_string(i));
                H5::Group materialOrientationGroup = materialOrientationsGroup.openGroup(name);
                isR &= readMaterialOrientation(materialOrientationGroup);
            }
        }

        //读取Inertia子节点
        if (_h5Group->nameExists("Inertias"))
        {
            H5::Group inertiasGroup = _h5Group->openGroup("Inertias");
            int inertiasCount = inertiasGroup.getNumAttrs();

            for (int i = 0; i < inertiasCount; ++i)
            {
                auto name = readStrAttribute(inertiasGroup, std::to_string(i));
                H5::Group inertiaGroup = inertiasGroup.openGroup(name);
                isR &= readInertia(inertiaGroup);
            }
        }

        //读取BeamOrientations子节点
        if (_h5Group->nameExists("BeamOrientations"))
        {
            H5::Group beamOrientationsGroup = _h5Group->openGroup("BeamOrientations");
            int beamOrientationsCount = beamOrientationsGroup.getNumAttrs();

            for (int i = 0; i < beamOrientationsCount; ++i)
            {
                auto name = readStrAttribute(beamOrientationsGroup, std::to_string(i));
                H5::Group beamOrientationGroup = beamOrientationsGroup.openGroup(name);
                isR &= readBeamOrientation(beamOrientationGroup);
            }
        }

        return isR;
    }

    bool FITKAbaqusHDF5AdaptorPart::adaptW()
    {
        _partData = AbaqusData::FITKAbaqusPart::SafeDownCastFITKAbaqusPart(_dataObj);
        if (!_partData || !_h5Group || !_writer) return false;
        bool isW = true;

        std::string groupName = createParentAttribute(_partData, *_h5Group);
        if (groupName.empty())return false;

        //创建Part子节点
        auto partGroup = _h5Group->createGroup(groupName);
        //创建Grid子节点
        H5::Group GridGroup = partGroup.createGroup("Grid");
        //写出节点
        isW &= writeNode(_partData, GridGroup);
        //写出单元
        isW &= writeElement(_partData, GridGroup);

        //创建sets子节点
        H5::Group setGroup = partGroup.createGroup("Sets");
        //写出集合与表面
        isW &= writeSetSurf(_partData, setGroup);
        //写出截面指派
        auto sectionAssignManager = _partData->getSectionAssignManager();
        if (!sectionAssignManager) return false;

        //创建sectionAssignGroup子节点
        H5::Group sectionAssignGroup = partGroup.createGroup("SectionAssigns");
        for (int i = 0; i < sectionAssignManager->getDataCount(); ++i)
        {
            auto sectionAssignData = sectionAssignManager->getDataByIndex(i);
            isW &= writeSectionAssign(sectionAssignData, sectionAssignGroup);
        }

        //创建CoordinateSystemGroup子节点
        auto coordinateSystemManager = _partData->getCoordinateSystemManager();
        if (!coordinateSystemManager) return false;
        H5::Group CoordinateSystemsGroup = partGroup.createGroup("CoordinateSystems");
        for (int i = 0; i < coordinateSystemManager->getDataCount(); ++i)
        {
            auto coordinateSystemData = coordinateSystemManager->getDataByIndex(i);
            isW &= writeCoordinateSystem(coordinateSystemData, CoordinateSystemsGroup);
        }

        //创建MaterialOrientationGroup子节点
        auto materialOrientationManager = _partData->getMaterialOrientationManager();
        if (!materialOrientationManager) return false;
        H5::Group MaterialOrientationsGroup = partGroup.createGroup("MaterialOrientations");
        for (int i = 0; i < materialOrientationManager->getDataCount(); ++i)
        {
            auto materialOrientationData = materialOrientationManager->getDataByIndex(i);
            isW &= writeMaterialOrientation(materialOrientationData, MaterialOrientationsGroup);
        }

        //创建Inertia子节点
        auto inertiaManager = _partData->getPartEngineerFeature()->getInertiaManager();
        if (!inertiaManager) return false;
        H5::Group inertiasGroup = partGroup.createGroup("Inertias");
        for (int i = 0; i < inertiaManager->getDataCount(); ++i)
        {
            auto inertiaData = inertiaManager->getDataByIndex(i);
            isW &= writeInertia(inertiaData, inertiasGroup);
        }

        //创建BeamOrientation子节点
        auto beamOManager = _partData->getBeamOrientationManager();
        if (!beamOManager) return false;
        H5::Group beamOrientationsGroup = partGroup.createGroup("BeamOrientations");
        for (int i = 0; i < beamOManager->getDataCount(); ++i)
        {
            auto beamOData = beamOManager->getDataByIndex(i);
            isW &= writeBeamOrientation(beamOData, beamOrientationsGroup);
        }


        isW &= writeNDataObject(_partData, partGroup);
        return isW;
    }


    bool FITKAbaqusHDF5AdaptorPart::readNode(AbaqusData::FITKAbaqusPart* partData, H5::Group& h5Group)
    {
        if (partData == nullptr) return false;
        return FITKInterfaceHDF5AdaptorMesh::readNode(partData->getMesh(), h5Group);
    }

    bool FITKAbaqusHDF5AdaptorPart::readElement(AbaqusData::FITKAbaqusPart* partData, H5::Group& h5Group)
    {
        if (partData == nullptr) return false;
        auto mesh = partData->getMesh();
        if (mesh == nullptr) return false;
        //创建Grid->Cells子节点 用于存储单元数据
        H5::Group eleGroup = h5Group.openGroup("Cells");
        //循环类型

        int EleTypeCount = eleGroup.getNumAttrs();
        for (int i = 0; i < EleTypeCount; ++i)
        {
            auto eleType = eleGroup.openAttribute(i);
            //name
            std::string elementTypeName;
            H5::StrType datatype(H5::PredType::C_S1, H5T_VARIABLE);
            eleType.read(datatype, elementTypeName);
            int n, m;
            if (!getDataSetDim(eleGroup, elementTypeName, n, m)) return false;

            hsize_t dimEleData[2]{ n ,m };

            H5::DataSpace eleDataSpace(2, dimEleData);
            H5::DataSet eleDataSet = eleGroup.openDataSet(elementTypeName);
            int i_Ele = -1;

            //枚举转换字符 确定解析的单元类型
            Core::FITKEnumTransfer<Interface::FITKAbaMeshPartVTK::AbaEleType> fitkEleTypeTrafer;
            bool isValid = false;
            auto elementType = fitkEleTypeTrafer.fromString(QString::fromStdString(elementTypeName), isValid);
            if (!isValid) return false;
            // 对同类单元进行每行循环读取数据
            for (int j = 0; j < n; ++j)
            {
                hsize_t start[2] = { ++i_Ele, 0 };  // hyperslab的开始
                hsize_t stride[2] = { 1, m };    // hyperslab的步长
                hsize_t count[2] = { 1, 1 };
                hsize_t block[2] = { 1, m };  // Block sizes
                eleDataSpace.selectHyperslab(H5S_SELECT_SET, count, start, stride, block);
                hsize_t dim[] = { m * 2 };

                H5::DataSpace mspace2(1, dim);
                hsize_t start2[1] = { 0 };
                hsize_t stride2[1] = { 1 };
                hsize_t count2[1] = { m };
                hsize_t block2[1] = { 1 };
                mspace2.selectHyperslab(H5S_SELECT_SET, count2, start2, stride2, block2);

                int* ptIDArray = new int[m];
                eleDataSet.read(ptIDArray, H5::PredType::NATIVE_INT, mspace2, eleDataSpace);
                QList<int> nodes;
                for (int k = 1; k < m; k++)
                {
                    nodes.append(ptIDArray[k]);
                }
                mesh->appendElement(elementType, ptIDArray[0], nodes);
                delete[] ptIDArray;
            }
        }
        return true;

    }

    bool FITKAbaqusHDF5AdaptorPart::readSetSurf(AbaqusData::FITKAbaqusPart* partData, H5::Group& h5Group)
    {
        if (!partData) return false;
        bool isR = true;
        auto setSurfManager = partData->getComponentManager();
        if (!setSurfManager)return false;
        //打开set子节点
        if (!h5Group.nameExists("Sets")) return false;
        H5::Group setsGroup = h5Group.openGroup("Sets");
        //组件节点数量
        int componentCount = setsGroup.getNumAttrs();
        for (int i = 0; i < componentCount; ++i)
        {
            QString componentIndex = QString::number(i);
            auto componentName = readStrAttribute(setsGroup, componentIndex.toStdString());
            if (!setsGroup.nameExists(componentName))
            {
                _reader->consoleMessage(3, QString("Read Component Error, name : %1").arg(QString::fromStdString(componentName)));
                continue;
            }
            auto componentGroup = setsGroup.openGroup(componentName);

            auto uniqueType = readStrAttribute(componentGroup, "UniqueType");
            auto TypeStr = readStrAttribute(componentGroup, "Type");
            if (uniqueType == "Set")
            {
                Interface::FITKModelSet *cSet = new Interface::FITKModelSet();
                setSurfManager->appendDataObj(cSet);
                bool r = readSet(cSet, setSurfManager, componentGroup);
                if (!r) delete cSet;
                isR &= r;
            }
            else if (uniqueType == "Surface")
            {
                Interface::FITKMeshSurface* surface{};

                //枚举转换字符
                Core::FITKEnumTransfer<Interface::FITKMeshSurface::MeshSurfaceType> fitkSurfTypeTrafer;
                bool isValid = false;
                //写出类型
                auto Type = fitkSurfTypeTrafer.fromString(QString::fromStdString(TypeStr), isValid);
                if (!isValid) return false;

                if (Type == Interface::MeshSurfaceType::SurNode)
                    surface = new Interface::FITKMeshSurfaceNode;
                else if (Type == Interface::MeshSurfaceType::SurEle)
                    surface = new Interface::FITKMeshSurfaceElement;
                else
                    return false;
                setSurfManager->appendDataObj(surface);
                bool r = readSurface(surface, componentGroup);
                if (!r) delete surface;
                isR &= r;
            }
            else
            {
                _reader->consoleMessage(3, QString("Read Component Error , UniqueType Error :%1").arg(QString::fromStdString(componentName)));
                continue;
            }
        }

        return isR;
    }

    bool FITKAbaqusHDF5AdaptorPart::readSet(Interface::FITKModelSet* set, Interface::FITKComponentManager* compManager, H5::Group& h5Group)
    {
        auto adaptor = FITKIOADAPTORFACTORY->createT<FITKInterfaceHDF5AdaptorSet>("HDF5", set);
        if (adaptor == nullptr) return false;
        adaptor->setFileReader(_reader);
        adaptor->setCompomentManager(compManager);
        adaptor->setDataObject(set);
        adaptor->setH5GroupData(h5Group);
        bool ok = adaptor->adaptR();
        delete adaptor;
        if (!ok) _writer->consoleMessage(3, QString("Read Part Set Error,File:%1 Line:%2").arg(__FILE__).arg(__LINE__));
        return ok;
    }

    bool FITKAbaqusHDF5AdaptorPart::readSurface(Interface::FITKMeshSurface* surface, H5::Group& h5Group)
    {
        //调用surface适配器读写
        auto adaptor = FITKIOADAPTORFACTORY->createT<FITKInterfaceHDF5AdaptorSurface>("HDF5", "Interface::FITKMeshSurface");
        if (adaptor == nullptr) return false;
        adaptor->setFileReader(_reader);
        adaptor->setDataObject(surface);
        adaptor->setH5GroupData(h5Group);
        bool ok = adaptor->adaptR();
        delete adaptor;
        if (!ok) _writer->consoleMessage(3, QString("Reader Part Surface Error,File:%1 Line:%2").arg(__FILE__).arg(__LINE__));
        return ok;
    }

    bool FITKAbaqusHDF5AdaptorPart::readSectionAssign(int sectionType, H5::Group& h5Group)
    {
        if (sectionType == -1) return false;
        Interface::FITKSectionAssign * sectionAssign;

        if (sectionType == Interface::FITKAbaAbastractSectionAssign::FITKAbaSectionAssignType::Beam)
        {
            sectionAssign = new Interface::FITKAbaSectionAssignBeam();
        }
        else if (sectionType == Interface::FITKAbaAbastractSectionAssign::FITKAbaSectionAssignType::ShellHomogeneous)
        {
            sectionAssign = new Interface::FITKAbaSectionAssignShellHomogeneous();
        }
        else if (sectionType == Interface::FITKAbaAbastractSectionAssign::FITKAbaSectionAssignType::SolidHomogeneous)
        {
            sectionAssign = new Interface::FITKAbaSectionAssignSolidHomogenous();
        }
        else if (sectionType == Interface::FITKAbaAbastractSectionAssign::FITKAbaSectionAssignType::Truss)
        {
            //sectionAssign = new Interface::FITKAbaSectionAssignTruss();
        }
        else
        {
            return false;
        }

        if (!sectionAssign) return false;
        _partData->getSectionAssignManager()->appendDataObj(sectionAssign);

        //调用assgin适配器读写
        auto adaptor = FITKIOADAPTORFACTORY->createT<FITKAbaqusHDF5AdaptorSectionAssign>("HDF5", "Interface::FITKAbaAbastractSectionAssign");
        if (adaptor == nullptr) return false;
        adaptor->setFileReader(_reader);
        adaptor->setDataObject(sectionAssign);
        adaptor->setH5GroupData(h5Group);
        bool ok = adaptor->adaptR();
        delete adaptor;
        if (!ok)
        {
            delete sectionAssign;
            _reader->consoleMessage(3, QString("Read Part SectionAssign Error,File:%1 Line:%2").arg(__FILE__).arg(__LINE__));
        }
        return ok;
    }

    bool FITKAbaqusHDF5AdaptorPart::readCoordinateSystem(H5::Group& h5Group)
    {
        auto partData = AbaqusData::FITKAbaqusPart::SafeDownCastFITKAbaqusPart(_dataObj);
        if (!partData) return false;
        bool isValid = false;

        if (!h5Group.attrExists("SysType")) return false;;
        auto sSysType = readStrAttribute(h5Group, "SysType");
        //枚举转换字符
        Core::FITKEnumTransfer<Interface::FITKCoordinateSystem::FCSysType> fitkTypeTrafer;
        auto eSysType = fitkTypeTrafer.fromString(QString::fromStdString(sSysType), isValid);
        if (!isValid) return false;

        Interface::FITKAbaTransform* transform = new Interface::FITKAbaTransform(eSysType);
        if (!transform)return false;
        partData->getCoordinateSystemManager()->appendDataObj(transform);
        //调用coordinateSystem适配器读写
        auto adaptor = FITKIOADAPTORFACTORY->createT<FITKAbaqusHDF5AdaptorCoordinateSystem>("HDF5", "Interface::FITKAbaTransform");
        if (adaptor == nullptr) return false;
        adaptor->setFileReader(_reader);
        adaptor->setDataObject(transform);
        adaptor->setH5GroupData(h5Group);
        bool ok = adaptor->adaptR();
        delete adaptor;
        if (!ok)
        {
            delete transform;
            _reader->consoleMessage(3, QString("Read Part CoordinateSystem Error,File:%1 Line:%2").arg(__FILE__).arg(__LINE__));
        }
        return ok;
    }

    bool FITKAbaqusHDF5AdaptorPart::readMaterialOrientation(H5::Group & h5Group)
    {
        auto partData = AbaqusData::FITKAbaqusPart::SafeDownCastFITKAbaqusPart(_dataObj);
        if (!partData) return false;

        Interface::FITKAbaMaterialOrientation* materialOrientation = new Interface::FITKAbaMaterialOrientation();
        if (!materialOrientation) return false;
        partData->getMaterialOrientationManager()->appendDataObj(materialOrientation);
        //调用coordinateSystem适配器读写
        auto adaptor = FITKIOADAPTORFACTORY->createT<FITKAbaqusHDF5AdaptorMaterialOrientation>("HDF5", "Interface::FITKAbaMaterialOrientation");
        if (adaptor == nullptr) return false;
        adaptor->setFileReader(_reader);
        adaptor->setDataObject(materialOrientation);
        adaptor->setH5GroupData(h5Group);
        bool ok = adaptor->adaptR();
        delete adaptor;
        if (!ok)
        {
            delete materialOrientation;
            _reader->consoleMessage(3, QString("Read Part MaterialOrientation Error, File:%1 Line:%2").arg(__FILE__).arg(__LINE__));
        }
        return ok;
    }

    bool FITKAbaqusHDF5AdaptorPart::readInertia(H5::Group & h5Group)
    {
        auto partData = AbaqusData::FITKAbaqusPart::SafeDownCastFITKAbaqusPart(_dataObj);
        if (!partData) return false;
        bool isValid = false;

        auto sInertiaType = readStrAttribute(h5Group, "InertiaType");
        //枚举转换字符
        Core::FITKEnumTransfer<Interface::FITKAbaAbstractInertia::FITKAbaInertiaType> fitkTypeTrafer;
        auto eInertiaType = fitkTypeTrafer.fromString(QString::fromStdString(sInertiaType), isValid);
        if (!isValid) return false;
        Interface::FITKAbaAbstractInertia* inertia{};
        if (eInertiaType == Interface::FITKAbaAbstractInertia::FITKAbaInertiaType::NonstructuralMass)
        {
            inertia = new Interface::FITKAbaInertiaPointMassInertia();
        }
        else if (eInertiaType == Interface::FITKAbaAbstractInertia::FITKAbaInertiaType::PointMassInertia)
        {
            return false;
        }
        else if (eInertiaType == Interface::FITKAbaAbstractInertia::FITKAbaInertiaType::HeatCapacitance)
        {
            return false;
        }
        else return false;

        auto partEngineerFeature = partData->getPartEngineerFeature();
        if (!partEngineerFeature) return false;
        auto inertaManager = partEngineerFeature->getInertiaManager();
        if (!inertaManager) return false;
        inertaManager->appendDataObj(inertia);

        //调用惯量适配器读写
        auto adaptor = FITKIOADAPTORFACTORY->createT<FITKAbaqusHDF5AdaptorInertia>("HDF5", "Interface::FITKAbaAbstractInertia");
        if (adaptor == nullptr) return false;
        adaptor->setFileReader(_reader);
        adaptor->setDataObject(inertia);
        adaptor->setH5GroupData(h5Group);
        bool ok = adaptor->adaptR();
        delete adaptor;
        if (!ok)
        {
            delete inertia;
            _reader->consoleMessage(3, QString("Read Part Inertia Error, File:%1 Line:%2").arg(__FILE__).arg(__LINE__));
        }
        return ok;
    }

    bool FITKAbaqusHDF5AdaptorPart::readBeamOrientation(H5::Group & h5Group)
    {
        auto partData = AbaqusData::FITKAbaqusPart::SafeDownCastFITKAbaqusPart(_dataObj);
        if (!partData) return false;

        Interface::FITKAbaBeamOrientation* beamO = new Interface::FITKAbaBeamOrientation();
        if (!beamO) return false;
        partData->getBeamOrientationManager()->appendDataObj(beamO);
        //调用梁方向适配器读写
        auto adaptor = FITKIOADAPTORFACTORY->createT<FITKAbstractHDF5Adaptor>("HDF5", beamO);
        if (adaptor == nullptr) return false;
        adaptor->setFileReader(_reader);
        adaptor->setDataObject(beamO);
        adaptor->setH5GroupData(h5Group);
        bool ok = adaptor->adaptR();
        delete adaptor;
        if (!ok)
        {
            delete beamO;
            _reader->consoleMessage(3, QString("Read Part BeamOrientation Error, File:%1 Line:%2").arg(__FILE__).arg(__LINE__));
        }
        return ok;
    }



    bool FITKAbaqusHDF5AdaptorPart::writeNode(AbaqusData::FITKAbaqusPart* partData, H5::Group& h5Group)
    {
        if (partData == nullptr) return false;
        return FITKInterfaceHDF5AdaptorMesh::writeNode(partData->getMesh(), h5Group);
    }

    bool FITKAbaqusHDF5AdaptorPart::writeElement(AbaqusData::FITKAbaqusPart* partData, H5::Group& h5Group)
    {
        if (partData == nullptr) return false;
        //添加abaqus单元类型
        auto mesh = partData->getMesh();
        if (mesh == nullptr) return false;
        //创建Grid->Cells子节点 用于存储单元数据
        H5::Group eleGroup = h5Group.createGroup("Cells");
        //key 单元类型名称 value单元编号
        QMultiHash<QString, int> elementType = extractElementInformation(mesh);
        QList<QString> typeNames = elementType.keys().toSet().toList();
        for (QString typeName : typeNames)
        {
            auto elIDList = elementType.values(typeName);
            auto ele = mesh->getElementByID(elIDList[0]);
            const int eleNodeCount = ele->getNodeCount();
            int i_Ele = -1;
            //行长度+1 将CellID 放在0的位置
            int lineSize = eleNodeCount + 1;
            hsize_t dimEleData[2]{ elIDList.size() ,lineSize };

            H5::DataSpace eleDataSpace(2, dimEleData);
            H5::DataSet eleDataSet = eleGroup.createDataSet(typeName.toStdString(), H5::PredType::NATIVE_INT, eleDataSpace);
            writeStrAttribute(eleDataSet, "EleType", typeName.toStdString());
            // 对同类单元进行循环
            for (int j = elIDList.size() - 1; j != -1; j--)
            {
                hsize_t start[2] = { ++i_Ele, 0 };  // hyperslab的开始
                hsize_t stride[2] = { 1, lineSize };    // hyperslab的步长
                hsize_t count[2] = { 1, 1 };
                hsize_t block[2] = { 1, lineSize };  // Block sizes
                eleDataSpace.selectHyperslab(H5S_SELECT_SET, count, start, stride, block);
                hsize_t dim[] = { lineSize * 2 };

                H5::DataSpace mspace2(1, dim);
                hsize_t start2[1] = { 0 };
                hsize_t stride2[1] = { 1 };
                hsize_t count2[1] = { lineSize };
                hsize_t block2[1] = { 1 };
                mspace2.selectHyperslab(H5S_SELECT_SET, count2, start2, stride2, block2);

                int* ptIDArray = new int[lineSize];
                for (int k = 0; k < eleNodeCount; ++k)
                    ptIDArray[k + 1] = mesh->getElementByID(elIDList[j])->getNodeID(k);
                ptIDArray[0] = elIDList[j];
                eleDataSet.write(ptIDArray, H5::PredType::NATIVE_INT, mspace2, eleDataSpace);
                delete[] ptIDArray;
            }

            //存储集合名称的链表 用index作为属性名称添加
            int numAttrCount = eleGroup.getNumAttrs();
            writeStrAttribute(eleGroup, std::to_string(numAttrCount), typeName.toStdString());
        }

        return true;
    }

    bool FITKAbaqusHDF5AdaptorPart::writeSetSurf(AbaqusData::FITKAbaqusPart* partData, H5::Group& h5Group)
    {
        auto setSurfManager = partData->getComponentManager();
        if (!setSurfManager)return false;
        int count = setSurfManager->getDataCount();
        bool ok = true;
        for (int i = 0; i < count; ++i)
        {
            QList<Interface::FITKModelSet*> setCombinationList;
            auto data = setSurfManager->getDataByIndex(i);
            QString name = data->getDataObjectName();
            Interface::FITKModelSet* set = dynamic_cast<Interface::FITKModelSet*>(data);
            Interface::FITKMeshSurface* surface = dynamic_cast<Interface::FITKMeshSurface*>(data);

            if (set)
            {
                ok &= writeSet(set, h5Group);
            }
            else if (surface)
            {
                ok &= writeSurface(partData, surface, h5Group);
            }
        }
        return ok;
    }

    bool FITKAbaqusHDF5AdaptorPart::writeSet(Interface::FITKModelSet * set, H5::Group& h5Group)
    {
        bool ok = false;
        auto adaptor = FITKIOADAPTORFACTORY->createT<FITKInterfaceHDF5AdaptorSet>("HDF5", set);
        if (adaptor == nullptr) return false;
        adaptor->setFileWriter(_writer);
        adaptor->setDataObject(set);
        adaptor->setH5GroupData(h5Group);
        ok = adaptor->adaptW();
        delete adaptor;
        if (!ok) _writer->consoleMessage(3, QString("Write Part Set Error,File:%1 Line:%2").arg(__FILE__).arg(__LINE__));
        return ok;
    }

    bool FITKAbaqusHDF5AdaptorPart::writeSurface(AbaqusData::FITKAbaqusPart* partData, Interface::FITKMeshSurface* surface, H5::Group& h5Group)
    {
        //调用surface适配器读写
        if (!partData)return false;
        auto adaptor = FITKIOADAPTORFACTORY->createT<FITKInterfaceHDF5AdaptorSurface>("HDF5", "Interface::FITKMeshSurface");
        if (adaptor == nullptr) return false;
        adaptor->setFileWriter(_writer);
        adaptor->setDataObject(surface);
        adaptor->setH5GroupData(h5Group);
        bool ok = adaptor->adaptW();
        delete adaptor;
        if (!ok) _writer->consoleMessage(3, QString("Write Part Surface Error,File:%1 Line:%2").arg(__FILE__).arg(__LINE__));
        return ok;
    }

    bool FITKAbaqusHDF5AdaptorPart::writeSectionAssign(Interface::FITKSectionAssign* sectionAssign, H5::Group& h5Group)
    {
        //调用assgin适配器读写
        if (!sectionAssign)return false;
        auto adaptor = FITKIOADAPTORFACTORY->createT<FITKAbaqusHDF5AdaptorSectionAssign>("HDF5", "Interface::FITKAbaAbastractSectionAssign");
        if (adaptor == nullptr) return false;
        adaptor->setFileWriter(_writer);
        adaptor->setDataObject(sectionAssign);
        adaptor->setH5GroupData(h5Group);
        bool ok = adaptor->adaptW();
        delete adaptor;
        if (!ok) _writer->consoleMessage(3, QString("Write Part SectionAssign Error,File:%1 Line:%2").arg(__FILE__).arg(__LINE__));
        return ok;
    }

    bool FITKAbaqusHDF5AdaptorPart::writeCoordinateSystem(Interface::FITKCoordinateSystem* coordinateSystem, H5::Group& h5Group)
    {
        //调用coordinateSystem适配器读写
        if (!coordinateSystem)return false;
        auto adaptor = FITKIOADAPTORFACTORY->createT<FITKAbaqusHDF5AdaptorCoordinateSystem>("HDF5", "Interface::FITKAbaTransform");
        if (adaptor == nullptr) return false;
        adaptor->setFileWriter(_writer);
        adaptor->setDataObject(coordinateSystem);
        adaptor->setH5GroupData(h5Group);
        bool ok = adaptor->adaptW();
        delete adaptor;
        if (!ok) _writer->consoleMessage(3, QString("Write Part CoordinateSystem Error, File:%1 Line:%2").arg(__FILE__).arg(__LINE__));
        return ok;
    }

    bool FITKAbaqusHDF5AdaptorPart::writeMaterialOrientation(Interface::FITKAbaMaterialOrientation* materialOrientation, H5::Group & h5Group)
    {
        //调用materialOrientation适配器读写
        if (!materialOrientation)return false;
        bool ok = false;
        auto adaptor = FITKIOADAPTORFACTORY->createT<FITKAbaqusHDF5AdaptorMaterialOrientation>("HDF5", "Interface::FITKAbaMaterialOrientation");
        if (adaptor == nullptr) return false;
        adaptor->setFileWriter(_writer);
        adaptor->setDataObject(materialOrientation);
        adaptor->setH5GroupData(h5Group);
        ok = adaptor->adaptW();
        delete adaptor;
        if (!ok) _writer->consoleMessage(3, QString("Write Part MaterialOrientation Error, File:%1 Line:%2").arg(__FILE__).arg(__LINE__));
        return ok;
    }

    bool FITKAbaqusHDF5AdaptorPart::writeInertia(Interface::FITKAbaAbstractInertia* inertia, H5::Group & h5Group)
    {
        //调用惯量适配器读写
        if (!inertia)return false;
        auto adaptor = FITKIOADAPTORFACTORY->createT<FITKAbaqusHDF5AdaptorInertia>("HDF5", "Interface::FITKAbaAbstractInertia");
        if (adaptor == nullptr) return false;
        adaptor->setFileWriter(_writer);
        adaptor->setDataObject(inertia);
        adaptor->setH5GroupData(h5Group);
        bool ok = adaptor->adaptW();
        delete adaptor;
        if (!ok) _writer->consoleMessage(3, QString("Write Part Inertia Error, File:%1 Line:%2").arg(__FILE__).arg(__LINE__));
        return ok;
    }

    bool FITKAbaqusHDF5AdaptorPart::writeBeamOrientation(Interface::FITKAbaBeamOrientation* beamO, H5::Group & h5Group)
    {
        //调用梁方向适配器读写
        if (!beamO)return false;
        auto adaptor = FITKIOADAPTORFACTORY->createT<FITKAbstractHDF5Adaptor>("HDF5", beamO);
        if (adaptor == nullptr) return false;
        adaptor->setFileWriter(_writer);
        adaptor->setDataObject(beamO);
        adaptor->setH5GroupData(h5Group);
        bool ok = adaptor->adaptW();
        delete adaptor;
        if (!ok) _writer->consoleMessage(3, QString("Write Part BeamOrientation Error, File:%1 Line:%2").arg(__FILE__).arg(__LINE__));
        return ok;
    }

    QMultiHash<QString, int> FITKAbaqusHDF5AdaptorPart::extractElementInformation(Interface::FITKUnstructuredMesh* mesh)
    {
        auto partMesh = dynamic_cast<Interface::FITKAbaMeshPartVTK*>(mesh);
        //key 单元类型名称 value单元编号
        QMultiHash<QString, int> elementType;
        if (partMesh == nullptr) return elementType;
        //枚举转换字符 确定解析的单元类型
        Core::FITKEnumTransfer<Interface::FITKAbaMeshPartVTK::AbaEleType> fitkEleTypeTrafer;
        bool isValid = false;
        //提取信息
        for (int i = 0; i < partMesh->getElementCount(); ++i)
        {
            auto eleType = partMesh->getAbaElementType(i);
            auto ele = partMesh->getElementAt(i);
            //枚举转换字符
            QString eleTypeStr = fitkEleTypeTrafer.toStrting(eleType, isValid);
            elementType.insert(eleTypeStr, ele->getEleID());
        }
        return elementType;
    }

}
